package larrys.pomodoro.security.entity;

import java.util.Collection;
import java.util.HashSet;

import larrys.pomodoro.domain.entity.PomodoroUser;
import larrys.pomodoro.domain.entity.Role;
import larrys.pomodoro.util.AssertUtil;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * A adapter(<i>follows the standard adapter design pattern</i>) between domain
 * entity <code>PomodoroUser</code> and Spring Security <code>UserDetails</code>
 * 
 * @author larry.li
 * 
 */
public class PomodoroUserDetailsAdapter implements UserDetails {

	private static final long serialVersionUID = 1L;

	private PomodoroUser user;
	private Collection<GrantedAuthority> authorities;

	public PomodoroUserDetailsAdapter(PomodoroUser user) {
		AssertUtil.argumentNotNull(user, "user");

		this.user = user;
		authorities = new HashSet<GrantedAuthority>();
		for (Role role : user.getRoles()) {
			authorities.add(new SimpleGrantedAuthority(role.getRoleName()));
		}
	}

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		return authorities;
	}

	@Override
	public String getPassword() {
		return user.getPassword();
	}

	/**
	 * <strong>&lt;IMPORTANT!&gt;</strong> this method actually returns the
	 * <code>email</code> property of <code>PomodoroUser</code> coz in my
	 * design, instead username, the email is the real unique id in whole system
	 * 
	 * @see org.springframework.security.core.userdetails.UserDetails#getUsername()
	 */
	@Override
	public String getUsername() {
		return user.getEmail();
	}

	@Override
	public boolean isAccountNonExpired() {
		return !user.isExpired();
	}

	@Override
	public boolean isAccountNonLocked() {
		return !user.isLocked();
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return !user.isCredentialsExpired();
	}

	@Override
	public boolean isEnabled() {
		return user.isEnabled();
	}

	public PomodoroUser getUser() {
		return user;
	}
}
